#include "MovingObstacle.h"
#include "Terrain.h"
#include <cmath>
#include <cstdlib>
#include <ctime>

MovingObstacle::MovingObstacle()
    : m_pMesh(NULL)
    , m_pTexture(NULL)
    , m_movementType(MOVEMENT_RANDOM)
    , m_size(D3DXVECTOR3(5.0f, 5.0f, 5.0f))
    , m_color(D3DCOLOR_XRGB(255, 200, 100))
    , m_velocity(D3DXVECTOR3(0, 0, 0))
    , m_speed(10.0f)
    , m_changeDirectionTimer(0.0f)
    , m_changeDirectionInterval(3.0f)
    , m_oscillateForward(true)
    , m_pStaticObjects(NULL)
    , m_pTerrain(NULL)
    , m_minX(50.0f)
    , m_maxX(950.0f)
    , m_minZ(50.0f)
    , m_maxZ(950.0f)
{
}

MovingObstacle::~MovingObstacle()
{
    Cleanup();
}

bool MovingObstacle::Initialize(LPDIRECT3DDEVICE9 device, MovementType moveType, const D3DXVECTOR3& size)
{
    m_movementType = moveType;
    m_size = size;

    // 创建立方体网格
    HRESULT hr = D3DXCreateBox(device, size.x, size.y, size.z, &m_pMesh, NULL);
    if (FAILED(hr))
        return false;

    // 设置包围盒（本地空间）
    m_boundingBox = AABB(
        D3DXVECTOR3(-size.x * 0.5f, -size.y * 0.5f, -size.z * 0.5f),
        D3DXVECTOR3(size.x * 0.5f, size.y * 0.5f, size.z * 0.5f)
    );

    // 创建程序纹理（与固定物体区分）
    hr = D3DXCreateTexture(device, 128, 128, 1, 0, D3DFMT_A8R8G8B8,
        D3DPOOL_MANAGED, &m_pTexture);

    if (SUCCEEDED(hr))
    {
        D3DLOCKED_RECT rect;
        m_pTexture->LockRect(0, &rect, NULL, 0);
        DWORD* pTexels = (DWORD*)rect.pBits;

        // Minecraft 风格的木头纹理（棕色方块贴图）
        for (int y = 0; y < 128; y++)
        {
            for (int x = 0; x < 128; x++)
            {
                // 基础颜色：棕色木头
                int r = 139;
                int g = 90;
                int b = 43;

                // 16x16 像素网格（Minecraft 风格）
                bool isBorder = (x % 16 == 0 || y % 16 == 0);
                if (isBorder)
                {
                    // 边框深色
                    r -= 30;
                    g -= 20;
                    b -= 10;
                }

                // 添加木头纹理的条纹效果
                if ((y / 8) % 2 == 0)
                {
                    r += 15;
                    g += 10;
                    b += 5;
                }

                // 添加随机噪点
                int noise = (rand() % 20) - 10;
                r += noise;
                g += noise;
                b += noise;

                // 确保颜色范围有效
                if (r < 80) r = 80; if (r > 180) r = 180;
                if (g < 50) g = 50; if (g > 120) g = 120;
                if (b < 20) b = 20; if (b > 80) b = 80;

                pTexels[y * 128 + x] = D3DCOLOR_ARGB(255, r, g, b);
            }
        }
        m_pTexture->UnlockRect(0);
    }

    // 初始化运动参数
    if (m_movementType == MOVEMENT_RANDOM)
    {
        ChangeRandomDirection();
    }
    else if (m_movementType == MOVEMENT_OSCILLATE)
    {
        // 往复运动：起点和终点暂时设为零，等SetPosition后再初始化
        m_oscillateStart = D3DXVECTOR3(0, 0, 0);
        m_oscillateEnd = D3DXVECTOR3(0, 0, 0);
    }

    return true;
}

void MovingObstacle::Update(float deltaTime)
{
    if (m_movementType == MOVEMENT_RANDOM)
    {
        UpdateRandomMovement(deltaTime);
    }
    else if (m_movementType == MOVEMENT_OSCILLATE)
    {
        UpdateOscillateMovement(deltaTime);
    }

    // 更新Y坐标以贴合地形
    if (m_pTerrain)
    {
        float terrainHeight = m_pTerrain->GetHeight(m_position.x, m_position.z);
        m_position.y = terrainHeight + m_size.y * 0.5f; // Box中心在原点，底部贴地
    }
}

void MovingObstacle::UpdateRandomMovement(float deltaTime)
{
    // 更新方向改变计时器
    m_changeDirectionTimer += deltaTime;
    if (m_changeDirectionTimer >= m_changeDirectionInterval)
    {
        ChangeRandomDirection();
        m_changeDirectionTimer = 0.0f;
    }

    // 保存旧位置
    D3DXVECTOR3 oldPosition = m_position;

    // 根据速度更新位置
    m_position += m_velocity * deltaTime;

    // 检查地图边界
    bool hitBoundary = false;
    if (m_position.x < m_minX || m_position.x > m_maxX)
    {
        m_velocity.x = -m_velocity.x;
        m_position.x = oldPosition.x;
        hitBoundary = true;
    }
    if (m_position.z < m_minZ || m_position.z > m_maxZ)
    {
        m_velocity.z = -m_velocity.z;
        m_position.z = oldPosition.z;
        hitBoundary = true;
    }

    // 检查与固定物体的碰撞
    if (CheckCollisionWithStaticObjects())
    {
        // 碰撞后反向并恢复位置
        m_velocity = -m_velocity;
        m_position = oldPosition;
        // 改变方向避免卡住
        ChangeRandomDirection();
    }

    if (hitBoundary)
    {
        // 碰到边界也改变方向
        ChangeRandomDirection();
    }
}

void MovingObstacle::UpdateOscillateMovement(float deltaTime)
{
    D3DXVECTOR3 target = m_oscillateForward ? m_oscillateEnd : m_oscillateStart;
    D3DXVECTOR3 direction = target - m_position;
    float distance = D3DXVec3Length(&direction);

    // 如果接近目标点，切换方向
    if (distance < 2.0f)
    {
        m_oscillateForward = !m_oscillateForward;
        target = m_oscillateForward ? m_oscillateEnd : m_oscillateStart;
        direction = target - m_position;
    }

    // 归一化方向并移动
    D3DXVec3Normalize(&direction, &direction);
    m_position += direction * m_speed * deltaTime;
}

void MovingObstacle::ChangeRandomDirection()
{
    // 随机角度（0-360度）
    float angle = (rand() % 360) * D3DX_PI / 180.0f;
    m_velocity.x = cos(angle) * m_speed;
    m_velocity.z = sin(angle) * m_speed;
    m_velocity.y = 0; // 不在Y轴移动
}

bool MovingObstacle::CheckCollisionWithStaticObjects()
{
    if (!m_pStaticObjects)
        return false;

    for (size_t i = 0; i < m_pStaticObjects->size(); i++)
    {
        GameObject* obj = (*m_pStaticObjects)[i];
        if (obj && CheckCollision(*obj))
        {
            return true;
        }
    }
    return false;
}

void MovingObstacle::Render(LPDIRECT3DDEVICE9 device)
{
    if (!device || !m_pMesh)
        return;

    // 设置世界矩阵
    D3DXMATRIX matWorld, matScale, matRot, matTrans;
    D3DXMatrixScaling(&matScale, m_scale.x, m_scale.y, m_scale.z);

    D3DXMATRIX matRotX, matRotY, matRotZ;
    D3DXMatrixRotationX(&matRotX, m_rotation.x);
    D3DXMatrixRotationY(&matRotY, m_rotation.y);
    D3DXMatrixRotationZ(&matRotZ, m_rotation.z);
    matRot = matRotX * matRotY * matRotZ;

    D3DXMatrixTranslation(&matTrans, m_position.x, m_position.y, m_position.z);

    matWorld = matScale * matRot * matTrans;
    device->SetTransform(D3DTS_WORLD, &matWorld);

    // 设置材质
    D3DMATERIAL9 material = {};
    BYTE r = (m_color >> 16) & 0xFF;
    BYTE g = (m_color >> 8) & 0xFF;
    BYTE b = m_color & 0xFF;

    material.Diffuse.r = material.Ambient.r = r / 255.0f;
    material.Diffuse.g = material.Ambient.g = g / 255.0f;
    material.Diffuse.b = material.Ambient.b = b / 255.0f;
    material.Diffuse.a = material.Ambient.a = 1.0f;
    device->SetMaterial(&material);

    // 设置纹理
    if (m_pTexture)
    {
        device->SetTexture(0, m_pTexture);
        device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
        device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    }

    // 渲染网格
    m_pMesh->DrawSubset(0);
}

void MovingObstacle::Cleanup()
{
    if (m_pTexture)
    {
        m_pTexture->Release();
        m_pTexture = NULL;
    }
    if (m_pMesh)
    {
        m_pMesh->Release();
        m_pMesh = NULL;
    }
}

void MovingObstacle::SetMovementBounds(float minX, float maxX, float minZ, float maxZ)
{
    m_minX = minX;
    m_maxX = maxX;
    m_minZ = minZ;
    m_maxZ = maxZ;
}

void MovingObstacle::SetStaticObjects(const std::vector<GameObject*>* staticObjects)
{
    m_pStaticObjects = staticObjects;
}

void MovingObstacle::InitializeOscillateMovement()
{
    // 初始化往复运动的起点和终点（在SetPosition后调用）
    if (m_movementType == MOVEMENT_OSCILLATE)
    {
        m_oscillateStart = m_position;
        float angle = (rand() % 360) * D3DX_PI / 180.0f;
        m_oscillateEnd = m_position + D3DXVECTOR3(
            cos(angle) * 100.0f,
            0,
            sin(angle) * 100.0f
        );
    }
}
